package com.yesep.learn.jwt.filter;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yesep.learn.jwt.common.LoginUser;
import com.yesep.learn.jwt.exception.UsernameOrPasswordEmpytException;

import cn.hutool.core.util.StrUtil;

/**
 * 验证用户名密码正确后，生成一个token，并将token返回给客户端 该类继承自UsernamePasswordAuthenticationFilter
 * attemptAuthentication ：接收并解析用户凭证。
 */
public class JWTLoginFilter extends UsernamePasswordAuthenticationFilter {

	public JWTLoginFilter(AuthenticationManager authenticationManager, AuthenticationSuccessHandler successHandler, AuthenticationFailureHandler failureHandler, String filterProcessesUrl) {
		this.setFilterProcessesUrl(filterProcessesUrl); // 这句代码很重要，设置登陆的url 要和 WebSecurityConfig 配置类中的.loginProcessingUrl 一致，如果不配置则无法执行
														// 重写的attemptAuthentication
														// 方法里面而是执行了父类UsernamePasswordAuthenticationFilter的attemptAuthentication（）
		this.setAuthenticationManager(authenticationManager); // AuthenticationManager 是必须的
		this.setAuthenticationSuccessHandler(successHandler); // 设置自定义登陆成功后的业务处理
		this.setAuthenticationFailureHandler(failureHandler); // 设置自定义登陆失败后的业务处理
	}

	// 接收并解析用户凭证
	@Override
	public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException {
		try {
			LoginUser user = new ObjectMapper().readValue(req.getInputStream(), LoginUser.class);
			if (StrUtil.isBlank(user.getUsername()) || StrUtil.isBlank(user.getPassword())) {
				throw new UsernameOrPasswordEmpytException("用户名或者密码为空");
			}
			// 动态密码、验证码处理
			// VerifyCodeHandler verifyCodeHandler =
			// SpringUtils.getBean(VerifyCodeHandler.class);
			// if (null != verifyCodeHandler) {
			// String vcode = user.getVcode();
			// if (!verifyCodeHandler.verify(vcode)) {
			// throw new VerifyCodeException(verifyCodeHandler.message());
			// }
			// }
			UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), new ArrayList<>());
			return this.getAuthenticationManager().authenticate(token);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

}
